﻿
Imports osi.fs.property

Public Class transform_property_wrapper(Of IT, OT)
    Inherits property_wrapper(Of IT)
    Implements iproperty(Of OT)

    Private ReadOnly IT_to_OT As convert_d(Of IT, OT) = Nothing
    Private ReadOnly OT_to_IT As convert_d(Of OT, IT) = Nothing

    Protected Sub New(ByVal p As iproperty(Of IT),
                      ByVal IT_to_OT As convert_d(Of IT, OT),
                      ByVal OT_to_IT As convert_d(Of OT, IT))
        MyBase.New(p)
        assert(Not IT_to_OT Is Nothing)
        assert(Not OT_to_IT Is Nothing)
        Me.IT_to_OT = IT_to_OT
        Me.OT_to_IT = OT_to_IT
    End Sub

    Public Function get_data(ByVal data As pointer(Of OT)) As eventComb _
                            Implements iproperty(Of OT).get_data
        Dim d As pointer(Of IT) = Nothing
        Dim ec As eventComb = Nothing
        Return New eventComb(Function() As Boolean
                                 d = New pointer(Of IT)()
                                 ec = p.get_data(d)
                                 Return waitfor(ec) AndAlso
                                        goto_next()
                             End Function,
                             Function() As Boolean
                                 If ec.end_result() Then
                                     assert(Not +d Is Nothing)
                                     Dim o As OT = Nothing
                                     Return IT_to_OT(+d, o) AndAlso
                                            eva(data, o) AndAlso
                                            goto_end()
                                 Else
                                     Return False
                                 End If
                             End Function)
    End Function

    Public Function get_set_data(ByVal d As _do(Of OT, Boolean)) As eventComb _
                                Implements iproperty(Of OT).get_set_data
        Return get_set_data(get_set_data_proxy(d))
    End Function

    Public Function get_set_data(ByVal d As get_set_data_d(Of OT)) As eventComb _
                                Implements iproperty(Of OT).get_set_data
        assert(Not d Is Nothing)
        Return p.get_set_data(Function(p As pointer(Of IT)) As eventComb
                                  Dim po As pointer(Of OT) = Nothing
                                  Dim ec As eventComb = Nothing
                                  Return New eventComb(Function() As Boolean
                                                           Dim o As OT = Nothing
                                                           If IT_to_OT(+p, o) Then
                                                               po = New pointer(Of OT)(o)
                                                               ec = d(po)
                                                               Return waitfor(ec) AndAlso
                                                                      goto_next()
                                                           Else
                                                               Return False
                                                           End If
                                                       End Function,
                                                       Function() As Boolean
                                                           Dim i As IT = Nothing
                                                           Return ec.end_result() AndAlso
                                                                  OT_to_IT(+po, i) AndAlso
                                                                  eva(p, i) AndAlso
                                                                  goto_end()
                                                       End Function)
                              End Function)
    End Function

    Public Function set_data(ByVal value As OT) As eventComb _
                            Implements iproperty(Of OT).set_data
        Return New eventComb(Function() As Boolean
                                 Dim i As IT = Nothing
                                 Return OT_to_IT(value, i) AndAlso
                                        waitfor(p.set_data(i)) AndAlso
                                        goto_end()
                             End Function)
    End Function
End Class
